package pe.org.cnl.congreso.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import pe.org.cnl.congreso.dao.BaseDAO;
import pe.org.cnl.congreso.dao.Busqueda;

/**
 * 
 * @author hectorsaira(amigo de miguel melgar)
 */
//por ahi lo marcaria como repository
@Repository
public abstract class BaseDAOImpl<Entidad, TipoLLave> extends
                HibernateDaoSupport implements Serializable, BaseDAO<Entidad, TipoLLave> {

    /**
     * 
     */
    private static final long serialVersionUID = -3115343391633897397L;
    protected Class<Entidad> clase;

    @SuppressWarnings("unchecked")
    public BaseDAOImpl() {
            super();
            this.clase = (Class<Entidad>) ((ParameterizedType) getClass()
                            .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#crear(Entidad)
	 */
    @Override
	public Entidad crear(Entidad entidad) {
            getHibernateTemplate().save(entidad);
            return entidad;
    }

    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#obtener(Id)
	 */
    @Override
	public Entidad obtener(TipoLLave id) {
            return (Entidad) getHibernateTemplate().get(this.clase, (Long)id);
    }

    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#modificar(Entidad)
	 */
    @Override
	public Entidad modificar(Entidad entidad) {
            getHibernateTemplate().update(entidad);
            return entidad;
    }

    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#eliminar(Entidad)
	 */
    @Override
	public void eliminar(Entidad entidad) {
            getHibernateTemplate().delete(entidad);
    }

    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#listar(pe.org.cnl.congreso.dao.Busqueda)
	 */
    @Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
    public List<Entidad> listar(final Busqueda filtro) {
            System.out.println("((Busqueda)filtro).getFirstResult()="+((Busqueda)filtro).getFirstResult());
            System.out.println("((Busqueda)filtro).getMaxResults()="+((Busqueda)filtro).getMaxResults());
        return (List<Entidad>)this.getHibernateTemplate().execute(
	           	new HibernateCallback() {
	                public Object doInHibernate(Session session) throws HibernateException, SQLException {
	                    Criteria busqueda = filtro.getExecutableCriteria(session);
	                    busqueda.setFirstResult(((Busqueda)filtro).getFirstResult());
	                    if (filtro.getMaxResults() > 0)
	                        busqueda.setMaxResults(((Busqueda)filtro).getMaxResults());
	                    return (List<Entidad>)busqueda.list(); 
	                }
	            });
    }
    
    /* (non-Javadoc)
	 * @see pe.org.cnl.congreso.dao.BaseDAO#count()
	 */
    @Override
	public long count() {
        @SuppressWarnings("rawtypes")
        List list = getHibernateTemplate().find( "select count(*) from " + clase.getName() + " x");
        Long count = (Long) list.get(0);
        return count.longValue();
    }

    @Override
	public void grabarTodos(List<Entidad> list) {
		getHibernateTemplate().saveOrUpdateAll(list);  
	}
    
    @Override
	public void eliminarXId(TipoLLave id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void eliminarTodos(List<Entidad> list) {
		// TODO Auto-generated method stub
		
	}
	
}
